1、漏洞相关信息
漏洞名称:Apache Dubbo反序列化漏洞
漏洞编号:CVE-2019-17564
漏洞描述:
Apache Dubbo是一个分布式框架,致力于提供高性能透明化的RPC远程服务调用方案,以及SOA服务治理方案。Apache Dubbo在实际应用场景中主要负责解决分布式的相关需求。
Apache Dubbo支持多种协议,官方推荐使用 Dubbo 协议,CVE-2019-17564是属于Apache Dubbo HTTP协议中的一个反序列化漏洞,该漏洞的主要原因在于当Apache Dubbo启用HTTP协议之后,Apache Dubbo在接受来自消费者的远程调用请求的时候存在一个不安全的反序列化行为,最终导致了远程任意代码执行。
2、影响版本
- 2.7.0 <= Apache Dubbo <= 2.7.4.1
- 2.6.0 <= Apache Dubbo <= 2.6.7
- Apache Dubbo = 2.5.x
3、环境搭建
下载地址:https://github.com/apache/dubbo-samples/tree/master/java/dubbo-samples-http
- 下载源码后,将Dubbo的版本改成2.7.3
搭建 zookeeper
在pom.xml中加入gadget,在利用中使用了反序列化工具ysoserial, 利用链CommonsCollections2 需要第三方库文件 commons-collections4
1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
4、漏洞利用
使用ysoserial生产反序列化文件
1
java -jar ysoserial-master-30099844c6-1.jar CommonsCollections2 "open /Applications/Calculator.app" > payload.ser
在
/org.apache.dubbo.samples.http.api.DemoService
接口POST输入序列化的文件内容
5、 漏洞分析
从返回结果的报错调用栈可以定位到入口点javax.servlet.http.HttpServlet.service
。
在javax.servlet.http.HttpServlet.service
断点调试,处理HTTP请求的request和response。
跟进到dubbo-2.7.3.jar!/org/apache/dubbo/remoting/http/servlet/DispatcherServlet
,会有一个if判断,如果handler对象为空就会返回404,提示”Service not found”,否则会继续调用handle方法。
继续跟进到dubbo-2.7.3.jar!/org/apache/dubbo/rpc/protocol/http/HttpProtocol
的
handle方法中,这里dubbo使用http协议传输数据交互,
handle方法首先会判断是否为POST请求,如果不是会返回500状态码,如果是POST请求会从request中获取remoteAddr和remotePort,然后会进入到
skeleton.handleRequest`处理。
跟进spring-web-4.3.16.RELEASE.jar!/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter
中的handleRequest
方法,这里调用的是 spring 的 httpinvoker ,其中 readRemoteInvocation 会处理我们传入的 request 对象。
跟进RemoteInvocation,会返回RemoteInvocation.readRemoteInvocation
的处理结果。
继续跟进,这里会调用doReadRemoteInvocation
来针对数据流进行处理
跟进doReadRemoteInvocation
,会进入到spring-context-4.3.16.RELEASE.jar!org/springframework/remoting/rmi
,反序列化的入口在这里,其中ois为我们传入的POST数据,由于我们没有对ois进行校验,直接调用readObject
方法,这就会导致RCE。
6、漏洞修复
在分析中可以知道Dubbo2.7.3中handleRequest主要是调用spring 的 httpinvoker,而在Dubbo2.7.5中是是通过jsonrpc,首先在/org/apache/dubbo/rpc/protocol/http/HttpProtocol
的handle
方法中会实例化一个JsonRpcServer对象skeleton来处理uri,紧接着调用skeleton对象中的handle方法
在/com/googlecode/jsonrpc4j
中的handle
方法中如果无法处理传输Java序列化字节流,就会抛出异常。